#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/select.h>

int main(int argc, const char *argv[]) {
    int udp_socket = 0;
    struct sockaddr_in myaddr, peeraddr;

    udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if(-1 == udp_socket) {
        perror("fail to socket");
        exit(1);
    }

    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(50000);
    myaddr.sin_addr.s_addr = inet_addr("192.168.1.80");
    if(-1 == bind(udp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
        perror("fail to bind");
        exit(1);
    }

    char buf[100];
    socklen_t len = sizeof(peeraddr);
    ssize_t ret_recv;

    //初始化 select
    fd_set readfds;
    struct timeval tv;
    while(1) {
        FD_ZERO(&readfds);
        FD_SET(udp_socket, &readfds);
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        int ret_select = select(udp_socket+1, &readfds, NULL, NULL, &tv);
        if(ret_select == -1) {
            perror("fail to select");
            exit(1);
        } else if(ret_select) {
            if(FD_ISSET(udp_socket, &readfds)) {
                bzero(buf, sizeof(buf));
                ret_recv = recvfrom(udp_socket, buf, sizeof(buf), 0, (struct sockaddr*)&peeraddr, &len);
                if(ret_recv < 0) {
                    perror("fail to recvfrom");
                    exit(1);
                } else {
                    printf("ip: %s port:%d buf: %s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);
                }
            }
        } else {
            printf("time out!\n");
            continue;
        }
    }

    return 0;
}

